<template>
    <div>
        <div style="border: 1px solid #ccc; margin-top: 10px;">
            <!-- 工具栏 -->
            <Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" />
            <!-- 编辑器 -->
            <Editor style="height: 500px; overflow-y: hidden;" :defaultConfig="editorConfig" v-model="html"
                @onChange="onChange" @onCreated="onCreated" />
        </div>
    </div>
</template>

<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IButtonMenu, SlateEditor, Boot, SlateTransforms, SlateElement, SlateNode } from '@wangeditor/editor'
import axios from 'axios'
//Audio
// 音频
class AudioMenu {

    constructor() {
        this.title = '音频' // 自定义菜单标题
        this.iconSvg = '<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 44V4H31L40 14.5V44H8Z" fill="#555" stroke="#555" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M32 14L26 16.9688V31.5" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><circle cx="20.5" cy="31.5" r="5.5" fill="#FFF" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>' // 可选
        this.tag = 'button'
    }

    // 获取菜单执行时的 value ，用不到则返回空 字符串或 false
    getValue (editor) {                              // JS 语法
        return ' hello '
    }

    // 菜单是否需要激活（如选中加粗文本，“加粗”菜单会激活），用不到则返回 false
    isActive (editor) {                    // JS 语法
        return false
    }

    // 菜单是否需要禁用（如选中 H1 ，“引用”菜单被禁用），用不到则返回 false
    isDisabled (editor) {                     // JS 语法
        return false
    }
    //上传功能
    uploadAudio (editor) {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = 'audio/*';
        input.onchange = (event) => {
            const file = event.target.files[0];
            // 处理上传逻辑，例如使用FormData发送文件到服务器端
            const formData = new FormData();
            formData.append('file', file);

            // 发送请求到服务器端的接口
            axios.post(request.baseURL + `/api/server/publish/uploadvedio`, formData)
                .then(response => {
                    const audioUrl = response.data.data.url;
                    // 将音频地址插入到编辑器
                    // const html = `<video poster width="auto" height="auto" controls="true"><source src=${audioUrl} type="video/mp4"></video>`
                    // editor.setHtml(html)
                    editor.dangerouslyInsertHtml(`<div data-w-e-type=\"video\" data-w-e-is-void>\n<video poster=\"\" controls=\"true\" width=\"auto\" height=\"auto\"><source src=\"${audioUrl}\" type=\"video/mp4\"/></video>\n</div>`)
                })
                .catch(error => {
                    console.error('上传音频失败', error);
                });
        };
        input.click();
    }
    // 点击菜单时触发的函数
    exec (editor, value) {                              // JS 语法
        if (this.isDisabled(editor)) return
        this.uploadAudio(editor)
    }

}
const AudioConf = {
    key: 'Audio', // 定义 menu key ：要保证唯一、不重复（重要）
    factory () {
        return new AudioMenu() // 把 `YourMenuClass` 替换为你菜单的 class
    },
}
Boot.registerMenu(AudioConf)
// 排版按钮
class setTypeMenu {

    constructor() {
        this.title = '排版' // 自定义菜单标题
        //this.iconSvg = '<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="36" height="36" rx="3" fill="none" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 30H16" stroke="#333" stroke-width="4" stroke-linecap="round"/><path d="M12 24H24" stroke="#333" stroke-width="4" stroke-linecap="round"/><path d="M12 18H20" stroke="#333" stroke-width="4" stroke-linecap="round"/></svg>'
        this.tag = 'button'
    }

    // 获取菜单执行时的 value ，用不到则返回空 字符串或 false
    getValue (editor) {                              // JS 语法
        return ' hello '
    }

    // 菜单是否需要激活（如选中加粗文本，“加粗”菜单会激活），用不到则返回 false
    isActive (editor) {                    // JS 语法
        return false
    }

    // 菜单是否需要禁用（如选中 H1 ，“引用”菜单被禁用），用不到则返回 false
    isDisabled (editor) {                     // JS 语法
        return false
    }

    // 点击菜单时触发的函数
    exec (editor, value) {                              // JS 语法
        if (this.isDisabled(editor)) return
        let html = JSON.parse(JSON.stringify(editor.children))
        // editor.selectAll()
        // editor.deleteFragment()
        editor.clear()
        html.map(item => {
            item.lineHeight = '2'
            item.indent = '2em'
            if (item.type && item.type === 'video') {
                item.width = '700px'
            }
            item.children.map(ele => {
                if (ele.type && ele.type === 'image') {
                    item.textAlign = 'center'
                    ele.style.width = '700px'
                } else if (ele.text) {
                    ele.fontSize = '16px'
                    ele.color = "rgb(0, 0, 0)"
                    ele.fontFamily = "微软雅黑"
                }
            })
            editor.insertNode(item)
        })
        console.log(html)
    }
}

const setTypeConf = {
    key: 'setType', // 定义 menu key ：要保证唯一、不重复（重要）
    factory () {
        return new setTypeMenu() // 把 `YourMenuClass` 替换为你菜单的 class
    },
}
Boot.registerMenu(setTypeConf)
import request from '../utils/request'
export default {
    name: 'MyEditor',
    props: {
        value: {
            type: String,
            default: "",
        },
    },
    components: { Editor, Toolbar },
    data () {
        return {
            editor: null,
            html: '',
            toolbarConfig: {
                // toolbarKeys: [ /* 显示哪些菜单，如何排序、分组 */ ],
                // excludeKeys: [ /* 隐藏哪些菜单 */ ],
                toolbarKeys: [
                    "headerSelect",
                    "blockquote",
                    "|",
                    "bold",
                    "underline",
                    "italic",
                    {
                        "key": "group-more-style",
                        "title": "更多",
                        "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path><path d=\"M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z\"></path></svg>",
                        "menuKeys": [
                            "through",
                            "code",
                            "sup",
                            "sub",
                            "clearStyle"
                        ]
                    },
                    "color",
                    "bgColor",
                    "|",
                    "fontSize",
                    "fontFamily",
                    "lineHeight",
                    "|",
                    "bulletedList",
                    "numberedList",
                    "todo",
                    {
                        "key": "group-justify",
                        "title": "对齐",
                        "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z\"></path></svg>",
                        "menuKeys": [
                            "justifyLeft",
                            "justifyRight",
                            "justifyCenter",
                            "justifyJustify"
                        ]
                    },
                    {
                        "key": "group-indent",
                        "title": "缩进",
                        "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z\"></path></svg>",
                        "menuKeys": [
                            "indent",
                            "delIndent"
                        ]
                    },
                    "|",
                    "emotion",
                    "insertLink",
                    {
                        "key": "group-image",
                        "title": "图片",
                        "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z\"></path></svg>",
                        "menuKeys": [
                            "insertImage",
                            "uploadImage"
                        ]
                    },
                    {
                        "key": "group-video",
                        "title": "视频",
                        "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z\"></path></svg>",
                        "menuKeys": [
                            "insertVideo",
                            "uploadVideo",
                        ]
                    },
                    "insertTable",
                    "codeBlock",
                    "divider",
                    "|",
                    "undo",
                    "redo",
                    "|",
                    'setType',
                    "fullScreen"
                ],
                "excludeKeys": [],
                insertKeys: {
                    index: 23, // 插入的位置，基于当前的 toolbarKeys 
                    keys: ['Audio']
                },
                "modalAppendToBody": false
            },
            editorConfig: {
                placeholder: '请输入内容...',
                // autoFocus: false,
                pasteFilterStyle:false,
                pasteTextHandle:true,
                pasteFilterTags:['style','script']
                // 所有的菜单配置，都要在 MENU_CONF 属性下
                MENU_CONF: {
                    uploadImage: {
                        server: request.baseURL + `/api/server/publish/uploadImg`,
                        // 超时时间，默认为 10 秒
                        timeout: 30 * 1000, // 5s
                        fieldName: "file",
                        // 将 meta 拼接到 url 参数中，默认 false
                        metaWithUrl: false, // join params to url
                        // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
                        meta: { dataKey: 0, bizType: "common" },
                        // 自定义增加 http  header
                        // headers: {
                        //   Accept: "text/x-json",
                        //   otherKey: "xxx"
                        // },
                        // 跨域是否传递 cookie ，默认为 false
                        withCredentials: true,
                        // 自定义增加 http  header
                        // headers: {
                        //   Accept: "text/x-json",
                        //   otherKey: "xxx"
                        // },
                        maxFileSize: 10 * 1024 * 1024, // 10M
                        base64LimitSize: 5 * 1024, // insert base64 format, if file's size less than 5kb
                        // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
                        allowedFileTypes: ["image/*"],
                        // 最多可上传几个文件，默认为 100
                        maxNumberOfFiles: 30,
                        onBeforeUpload (file) {
                            console.log("onBeforeUpload", file);

                            return file; // will upload this file
                            // return false // prevent upload
                        },
                        onProgress (progress) {
                            console.log("onProgress", progress);
                        },
                        onSuccess (file, res) {
                            console.log("onSuccess", file, res);
                        },
                        onFailed (file, res) {
                            alert(res.message);
                            console.log("onFailed", file, res);
                        },
                        onError (file, err, res) {
                            alert(err.message);
                            console.error("onError", file, err, res);
                        }
                    },
                    uploadVideo: {
                        server: request.baseURL + `/api/server/publish/uploadvedio`,
                        fieldName: "file",
                        // 单个文件的最大体积限制，默认为 10M
                        maxFileSize: 50000 * 1024 * 1024, // 5M
                        // 最多可上传几个文件，默认为 5
                        maxNumberOfFiles: 10,
                        // 选择文件时的类型限制，默认为 ['video/*'] 。如不想限制，则设置为 []
                        allowedFileTypes: ["video/*"],
                        // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
                        meta: { dataKey: 0, bizType: "video" },
                        // 将 meta 拼接到 url 参数中，默认 false
                        metaWithUrl: false,
                        // 自定义增加 http  header
                        // headers: {
                        //   Accept: "text/x-json",
                        //   otherKey: "xxx"
                        // },
                        // 跨域是否传递 cookie ，默认为 false
                        withCredentials: true,
                        // 超时时间，默认为 30 秒
                        timeout: 30 * 1000, // 15 秒
                        // 上传进度的回调函数
                        onProgress (progress) {
                            console.log("progress", progress);
                        },
                        // 单个文件上传成功之后
                        onSuccess (file, res) {
                            console.log(`${file.name} 上传成功`, res);
                        },
                        // 单个文件上传失败
                        onFailed (file, res) {
                            console.log(`${file.name} 上传失败`, res);
                        },
                        // 上传错误，或者触发 timeout 超时
                        onError (file, err, res) {
                            console.log(`${file.name} 上传出错`, err, res);
                        }
                    },

                }
            }
        }
    },
    // watch: {
    //     value: {
    //         handler (val) {
    //             if (val !== this.html) {
    //                 this.html = val === null ? "" : val;
    //                 this.html = val
    //             }
    //         },
    //         immediate: true,
    //     },
    // },
    methods: {
        onCreated (editor) {
            this.editor = Object.seal(editor) // 【注意】一定要用 Object.seal() 否则会报错
            this.html = this.value
        },
        onChange (editor) {
            this.$emit("input", editor.getHtml());
            //console.log('onChange', editor.getHtml()) // onChange 时获取编辑器最新内容
        },
    },
    mounted () {

    },
    beforeDestroy () {
        const editor = this.editor
        if (editor == null) return
        editor.destroy() // 组件销毁时，及时销毁 editor ，重要！！！
    },
}
</script>

<style src="@wangeditor/editor/dist/css/style.css"></style>
